package com.lian.aieduc.service.Impl;

import com.lian.aieduc.mapper.UsersMapper;
import com.lian.aieduc.model.dto.*;
import com.lian.aieduc.model.po.User;
import com.lian.aieduc.model.vo.UserVO;
import com.lian.aieduc.service.UsersService;
import com.lian.aieduc.utils.*;
import jakarta.mail.MessagingException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.simple.SimpleLogger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Map;

@Service
@RequiredArgsConstructor
@Slf4j
public class UserServiceImpl implements UsersService {
    private final UsersMapper usersMapper;
    private final RedisUtil redisUtil;
    private final SmsSenderUtil smsSenderUtil;
    private final MailSenderUtil mailSenderUtil;

    public static String extractToken(String bearerToken) {
        log.info("bearerToken:{}", bearerToken);
        if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
            // 以空格为分隔符分割字符串，取第二个元素（索引为1）作为令牌
            return bearerToken.split(" ")[1];
        }
        return bearerToken;
    }

    @Override
    public Result<String> signInEmail(SignUpEmailDTO signUpEmailDTO) {
        if(signUpEmailDTO.getCode() ==null) {
            return Result.failure("请填写验证码");
        }

        // 获取验证码
        String code = (String)redisUtil.get(signUpEmailDTO.getEmail());
        if (code == null)
            return Result.failure("请先发送验证码");

        if (!code.equals(signUpEmailDTO.getCode()))
            return Result.failure("验证码错误");

        User user = usersMapper.findUserByEmail(signUpEmailDTO.getEmail());
        if (user == null) {
            User newUser = User.builder().email(signUpEmailDTO.getEmail()).nickname(signUpEmailDTO.getEmail()).build();

            usersMapper.insertUser(newUser);
            String token = JwtUtil.generateTokenWithUserId(newUser.getId());

            return Result.success("用户未注册，将自动注册", token);
        }

        String token = JwtUtil.generateTokenWithUserId(user.getId());

        return Result.success("登录成功", token);
    }

    @Override
    public Result<String> sendSMS(SendSmsDTO sendSmsDTO) {
        log.info("phoneNumber：{}", sendSmsDTO.getPhoneNumber());
        /**是否存在该验证码*/
        Boolean isExist = redisUtil.hasKey(sendSmsDTO.getPhoneNumber());
        log.info("isExist:{}", isExist);
        if (isExist)
            return Result.failure("60秒内不能重复发送");

        // 真正发送验证码逻辑
        String code = smsSenderUtil.sendSms(sendSmsDTO.getPhoneNumber());
    redisUtil.set(sendSmsDTO.getPhoneNumber(),code,60);
        return Result.success("发送成功");
    }

    @Override
    public Result<String> signInSms(SmsSignInDTO smsSignInDTO) {
        if(smsSignInDTO.getCode() == null) {
            return Result.failure("请填写验证码");
        }

        // 获取验证码
        String code = (String)redisUtil.get(smsSignInDTO.getPhoneNumber());

        if (!code.equals(smsSignInDTO.getCode()))
            return Result.failure("验证码错误");

        User user = usersMapper.findUserByPhone(smsSignInDTO.getPhoneNumber());

        if (user != null) {
            // 用户用户已存在直接返回token
            String token = JwtUtil.generateTokenWithUserId(user.getId());
            return Result.success("用户已存在直接登录", token);
        }

        User newUser = User.builder().phoneCode(smsSignInDTO.getPhoneNumber()).nickname(smsSignInDTO.getPhoneNumber())
            .build();
        // 不存在则注册
        usersMapper.insertUser(newUser);
        String token = JwtUtil.generateTokenWithUserId(newUser.getId());
        return Result.success(token);
    }

    @Override
    public Result<String> sendEmailCode(SendMailCodeDTO sendMailCodeDTO) throws MessagingException {

        Boolean isExist = redisUtil.hasKey(sendMailCodeDTO.getEmail());

        if (isExist)
            return Result.failure("60秒内不能重新发送");

        // 发送邮箱验证码的逻辑
        Integer code = mailSenderUtil.sendEmailCode(sendMailCodeDTO.getEmail());
        // 发送之后存储到redis上 并设置过期时间为 五分钟
        redisUtil.set(sendMailCodeDTO.getEmail(), code, 60);
        return Result.success("发送成功");
    }

    @Override
    public Result<UserVO> getUserById(Long userId) {
        return Result.success(usersMapper.getUserInfoById(userId));
    }

    @Override
    public Long pareTokenGetUserId(String authorization) {
        String token = extractToken(authorization);
        try {
            Map<String, Object> claims = JwtUtil.parseToken(token);

            return Long.parseLong(claims.get("userId").toString());
        } catch (Exception e) {
            return null;
        }
    }

    @Override
    @Transactional
    public Result<UserVO> updateUserInfoById(Long userId, UserInfoDTO userInfoDTO) {
        try {
            User user = User.builder().nickname(userInfoDTO.getNickname()).id(userId).bgUrl(userInfoDTO.getBgUrl())
                .avatarUrl(userInfoDTO.getAvatarUrl()).intro(userInfoDTO.getIntro()).realName(userInfoDTO.getRealName())
                .email(userInfoDTO.getEmail()).phoneCode(userInfoDTO.getPhoneCode()).qqCode(userInfoDTO.getQqCode())
                .gender(userInfoDTO.getGender()).bgUrl(userInfoDTO.getBgUrl()).build();
            usersMapper.updateUserById(user);

            UserVO userVO = usersMapper.getUserInfoById(userId);


            return Result.success(userVO);
        } catch (Exception e) {
            return Result.failure("更新用户数据失败");
        }
    }

}
